#include "BMP.h"
#include "../hexreader/hexreader.h"
#include <vector>

bool IMG::loadBMP(std::string path)
{
    std::ifstream file(path, std::ios::binary | std::ios::ate);
    if(!file.is_open())
    {
        return 0;
    }
    std::streampos fileSize = file.tellg(); 
    file.seekg(0, std::ios::beg);
    std::vector<uint8_t> _data;

    file.read((char*)&imghead.filetype,2);
    file.read((char*)&imghead.filesize,4);
    file.read((char*)&imghead.reserveddata1,2);
    file.read((char*)&imghead.reserveddata2,2);
    file.read((char*)&imghead.dataoffset,4);
    file.read((char*)&imginfo.length,4);
    file.read((char*)&imginfo.imgWidth,4);
    file.read((char*)&imginfo.imgHight,4);
    file.read((char*)&imginfo.planes,2);
    file.read((char*)&imginfo.bitcount,2);
    file.read((char*)&imginfo.compression,2);
    file.read((char*)&imginfo.imgsize,4);
    file.read((char*)&imginfo.XPelsPerMeter,4);
    file.read((char*)&imginfo.YPelsPerMeter,4);
    file.read((char*)&imginfo.colorNum,4);
    file.read((char*)&imginfo.importColorNum,4);


    
    if(imginfo.bitcount == 24)
    {
        for(int i = 0;i < (int)fileSize - 54;i++)
        {
            uint8_t middle;
            file.read((char*)&middle,sizeof(middle));
            _data.emplace_back(middle);
        }
        for(int h = 0;h < 3;h++)
        {
            std::vector<std::vector<uint8_t> > img;
            for(int i = 0; i < imginfo.imgWidth;i++)
            {
                std::vector<uint8_t> col;
                for(int j = 0; j < imginfo.imgHight;j++)
                {
                    col.emplace_back(_data[i * imginfo.imgWidth + j * imginfo.imgHight + h]);
                }
                img.emplace_back(col);
            }
            data.emplace_back(img);
        }
    }
    else if(imginfo.bitcount == 32)
    {
        for(int i = 0;i < (int)fileSize - 54;i++)
        {
            uint8_t middle;
            file.read((char*)&middle,sizeof(middle));
            _data.emplace_back(middle);
        }
        for(int h = 0;h < 4;h++)
        {
            std::vector<std::vector<uint8_t> > img;
            for(int i = 0; i < imginfo.imgWidth;i++)
            {
                std::vector<uint8_t> col;
                for(int j = 0; j < imginfo.imgHight;j++)
                {
                    col.emplace_back(_data[i * imginfo.imgWidth + j * imginfo.imgHight + h]);
                }
                img.emplace_back(col);
            }
            data.emplace_back(img);
        }
    }
    return 1;
}

bool cvtcolor(IMG &src,IMG &dst)
{

    if(src.type == GREY)
        return 0;
    dst.data.clear();
    std::vector<std::vector<uint8_t> >middle2;
    int temp = 0;
    for(int i = 0; i < src.imginfo.imgWidth;i++)
    {
        std::vector<uint8_t> middle1;
        for(int j = 0; j < src.imginfo.imgHight;j++)
        {         
            temp = 0;
            temp +=  src.data[0][i][j] * 0.114 ;
            temp += src.data[1][i][j] * 0.587 ;
            temp += src.data[2][i][j] * 0.299;
            middle1.emplace_back((uint8_t)temp);
        }
        middle2.emplace_back(middle1);            
    }    
    dst.data.emplace_back(middle2);
    dst.type = GREY;
    return 1;
}

bool drawhistogram(IMG &src,int number)
{
    if(src.type != GREY)
        return 0;
    std::vector<int> count;
    int todiv = 256 / (number - 1);
    for(int i = 0; i < number;i++)
        count.emplace_back(0);
    for(int i = 0 ;i < src.data[0].size();i++)
    {
        for(int j = 0;j < src.data[0][0].size();j++)
        {
            if(src.data[0][i][j]%todiv)
            {
                int div = src.data[0][i][j] / todiv + 1;
                count[div] += 1;
            }
            else 
            {
                int div = src.data[0][i][j] / todiv;
                count[div] += 1;
            }
        }
    }
    int maxValue = 0;
    for(int i = 0;i< count.size();i++)
    {
        if(count[i] > maxValue)
            maxValue = count[i];
    }

    for (int i = 0; i < count.size(); ++i) 
    {
        if (count[i] != 0) 
        {
            std::cout << i << "-" << i + 1 << ": ";
            int numStars = static_cast<int>(static_cast<double>(count[i]) / maxValue * 50);
            for (int j = 0; j < numStars; ++j) {
                std::cout << "*";
            }
            std::cout << std::endl;
        }
    }
    return 1;
}